package com.xjj.controller;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.xjj.entity.Parent;
import com.xjj.entity.ResponseEntity;
import com.xjj.entity.Vote;
import com.xjj.entity.VoteOption;
import com.xjj.service.AppVoteService;
import com.xjj.service.VoteService;
import com.xjj.util.utils.JwtUtil;
import com.xjj.vo.VotingVo;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static com.xjj.utils.RedisCache.*;

/**
 * @ClassName AppVoteController
 * @Description TODO
 * @Author GH
 * @Date 2022/10/21 16:56
 * @Version 1.0
 **/
@Slf4j
@RestController
@RequestMapping("/vote/api")
@Api(tags = "app投票接口")
public class AppVoteController {
    @Resource
    private VoteService voteService;

    @Resource
    private AppVoteService appVoteService;

    @Resource
    private RedisTemplate redisTemplate;


    @GetMapping("/getParent")
    public ResponseEntity getUserInfo(HttpServletRequest request) throws JsonProcessingException {
        String token = request.getHeader("token");
        Parent parent = JwtUtil.getParent(token);
        return ResponseEntity.SUCCESS("捕获双亲",parent);
    }
    /**
     * @param klassId: 班级id
     * @param current: 当前页
     * @return ResponseEntity
     * @author GH
     * @description TODO 获取本班现有投票列表
     * @date 2022/10/27 14:10
     */
    @GetMapping("/getVotes/{klassId}/{current}")
    public ResponseEntity getVotes(
            @PathVariable("klassId") Integer klassId,
            @PathVariable("current") Integer current){
        Map votesMap = redisTemplate.opsForHash().entries(CACHE_VOTELIST_KEY+klassId+":"+current);
        log.debug("votesMap:{}",votesMap.isEmpty());
        if(votesMap.isEmpty()){
            if(current==0){
                Page<Vote> votePage = voteService.getVotes(klassId,1);
                Map<String, Object> votePageMap = BeanUtil.beanToMap(votePage);
                redisTemplate.opsForHash().putAll(CACHE_VOTELIST_KEY+klassId+":"+current,votePageMap);
                redisTemplate.expire(CACHE_VOTELIST_KEY+klassId+":"+current,VOTELIST_TIMEOUT, TimeUnit.MINUTES);
                return new ResponseEntity<>(200,"ok",votePage);
            }else{
                Page<Vote> votePage = voteService.getVotes(klassId,current);
                Map<String, Object> votePageMap = BeanUtil.beanToMap(votePage);
                redisTemplate.opsForHash().putAll(CACHE_VOTELIST_KEY+klassId+":"+current,votePageMap);
                redisTemplate.expire(CACHE_VOTELIST_KEY+klassId+":"+current,VOTELIST_TIMEOUT, TimeUnit.MINUTES);
                return new ResponseEntity<>(200,"ok",votePage);
            }
        }else {
            Page page = BeanUtil.mapToBean(votesMap,Page.class,false);
            return new ResponseEntity<>(200,"ok",page);
        }
    }

    /**
     * @param id: 本条投票的id
     * @return ResponseEntity<Vote>
     * @author GH
     * @description TODO 获取本条投票详情
     * @date 2022/10/27 14:11
     */
    @GetMapping("/getDetails/{id}")
    public ResponseEntity<Vote> getDetails(@PathVariable Integer id){
        Map detailsMap = redisTemplate.opsForHash().entries(CACHE_VOTEDETAILS_KEY + id);
        if(detailsMap.isEmpty()){
            Vote vote = voteService.getDetailsById(id);
            Map<String, Object> beanToMap = BeanUtil.beanToMap(vote);
            redisTemplate.opsForHash().putAll(CACHE_VOTEDETAILS_KEY + id,beanToMap);
            redisTemplate.expire(CACHE_VOTEDETAILS_KEY + id,VOTEDETAILS_TIMEOUT, TimeUnit.MINUTES);
            return ResponseEntity.SUCCESS("ok",vote);
        }else {
            Vote vote = BeanUtil.mapToBean(detailsMap, Vote.class, false);
            return ResponseEntity.SUCCESS("ok",vote);
        }
    }

    @PutMapping("/voting")
    public ResponseEntity voting(@RequestBody VotingVo votingVo){
        Integer studentId = votingVo.getStudentId();
        Integer voteId = votingVo.getVoteId();
        Integer[] optionsId = votingVo.getOptionsId();
        //查询缓存中该学生id是否已有该条投票的数据,若有则返回已投票
//        VotingVo reslut = (VotingVo) redisTemplate.opsForValue().get(CACHE_OPTIONSTUDENT_KEY+studentId+":"+voteId );
//        System.out.println("从缓存中获取的votingvo:"+reslut);
//        if(reslut!=null){
//            return ResponseEntity.FAIL("你已过投票了",null);
//        }
        //将votingVo存入xjj_vote_parent表
        appVoteService.addStudentVote(votingVo);
        //将该投票数据存入缓存
        redisTemplate.opsForValue().set(CACHE_OPTIONSTUDENT_KEY+studentId+":"+voteId,votingVo);
        //将vote中的voted_num加1
        redisTemplate.opsForHash().increment(CACHE_VOTEDETAILS_KEY+voteId,"votedNum",1);
        //将该条vote中对应的选项num加1
        List<VoteOption> voteOption = (List<VoteOption>) redisTemplate.opsForHash().get(CACHE_VOTEDETAILS_KEY + voteId, "voteOption");
        for (Integer optionId : optionsId) {
            for (VoteOption option : voteOption) {
                if(option.getId().equals(optionId)){
                    option.setNum(option.getNum()+1);
                }
            }
        }
        redisTemplate.opsForHash().put(CACHE_VOTEDETAILS_KEY+voteId,"voteOption",voteOption);
        //响应
        return ResponseEntity.SUCCESS("投票成功",null);
    }

    @GetMapping("/hasVoting/{studentId}/{voteId}")
    public ResponseEntity hasVoting(@PathVariable("studentId") Integer studentId,
                                    @PathVariable("voteId") Integer voteId){
        //查询缓存中该学生id是否已有该条投票的数据,若有则返回已投票
        VotingVo reslut = (VotingVo) redisTemplate.opsForValue().get(CACHE_OPTIONSTUDENT_KEY+studentId+":"+voteId );
        System.out.println("从缓存中获取的votingvo:"+reslut);
        if(reslut!=null){
            return new ResponseEntity(119,"你已过投票了",null);
        }else {
            //若为空则查数据库是否有该条投票数据
            boolean hasVoting = appVoteService.hasVoting(studentId, voteId);
            if(hasVoting){
                return new ResponseEntity(119,"你已过投票了",null);
            }else {
                return ResponseEntity.SUCCESS("开始投票",null);
            }
        }
    }
}
